<?php

abstract class gObject
{
	public function init(){
		
	}	
	
	public function _hasParam() {
		$args = func_get_args();
		return call_user_func_array(array('gRequest','hasParam'), $args);
	}
	
	public function _getParams() {
		return gRequest::getParams();
	}
	
	public function _getParam() {
		$num = func_num_args();
		$params = func_get_args();
		if( $num == 1){ 
			return gRequest::getParam($params[0]);
		}
		else if( $num > 1) {
			$toReturn = array();
			foreach( $params as $key){
				if( gRequest::hasParam($key))
					$toReturn[$key] = gRequest::getParam($key);
			}
			return $toReturn;
		} else return false;
	}
}


abstract class gCoreObject extends gObject
{

	/**
	 * 
	 * Enter description here ...
	 * @var gInit
	 */
    protected $core   = null;
	
    /**
     * 
     * Enter description here ...
     * @var unknown_type
     */
    private $adapters = array();
    /**
     * Kernel object constructor, based on some php hacks
     *
     * @param ginit $Gepard     Link to preinitialized Gepard object
     */
    
    protected $_binded = array();
    
    function __construct($Gepard){

        $this->core = $Gepard;
    }

    /**
     * Gepard kernel object initialization method
     * Use it instead of __construct()
     */
    public function init()
    {
        
    }
    
    public function prepare()
    {
    	
    }
    
    public function bind($key,$value=null)
    {
    	$key = '_'.$key;
    	$this->$key = $value;
    }
    
    public function getclassname()
    {
    	return strtolower(substr(get_class($this),1,strlen(get_class($this))));
    }
    
    public function getAdapter($name)
    {
        if( !array_key_exists($name, $this->adapters))
        {
            $objname = $this->getclassname();
            $filename = _CORE_PATH.'classes'.DIRECTORY_SEPARATOR.$objname.DIRECTORY_SEPARATOR."adapters".DIRECTORY_SEPARATOR.$name.'.php';
            if( !file_exists($filename))
            {
                throw new Exception("Cannot find adapter file '$filename'");
            }
            require_once $filename;
            if( $interface!=null && !($classname instanceof $interface) )
            {
                throw new Exception('Adapter '.$name.' is not supported by interface');
            }
            $classname = get_class($this) .$name;
            $this->adapters[$name] = new $classname($this->core);
        }
        return $this->adapters[$name];
    }

    public function getAdaptersPool()
    {
        return $this->adapters;
    }

    function __clone()
    {
        
    }

    /**
     * Do nothing
     *
     * @param string $string
     * @return mixed
     */
    public function void($string = null){
        if( $string!=null){
            return $string;
        } else {
            return get_class($this);
        }
    }
}


abstract class gModule extends gObject
{
	/**
	 * 
	 * Enter description here ...
	 * @var gInit
	 */
	protected $api = null;
	
	function __construct( $Gepard )
	{
		$this->api = $Gepard;
	}
	
}

abstract class gModel extends gModule {
	
}
abstract class gController extends gModule {
	
	public function preDispatch(){
		
	}
	public function postDispatch(){
		
	}
}

abstract class gRestController extends gController {
	public function provide()
	{
		switch( gRequest::getMethod() ){
			case gRequest::REQ_GET : $action = 'list'; break;
			case gRequest::REQ_PUT : $action = 'update'; break;
			case gRequest::REQ_POST : $action = 'create'; break;
			case gRequest::REQ_DELETE : $action = 'delete'; break;
			default: $action = 'list'; break;
		}
		ob_start();
		$response = $this->$action();
		$buffer = ob_get_flush();
		if( strtolower($this->_getParam('format')) == 'json')
			print json_encode(array('result'=>$response,'output'=>$buffer));
		else 
			print (!empty($buffer) ? $buffer : null).$response;
	}
}

abstract class gRestAbstract
{
	public function create(){}
	public function update(){}
	public function read(){}
	public function delete(){}
}

